package com.rtsapp.server.gamelog.api;

import com.rtsapp.server.gamelog.api.logger.RollingCalendar;
import com.rtsapp.server.gamelog.api.logger.RollingLogger;
import com.rtsapp.server.gamelog.api.model.*;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by admin on 16-7-11.
 */
public class GameLogUtils {

    private static final ThreadLocal<SimpleDateFormat> threadLocalSDF = new ThreadLocal<>( );
    private static ThreadLocal<StringBuilder> sbLocal = new ThreadLocal();

    private static ThreadLocal<RegisterLog> registerThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger registerLogger;
    private static ThreadLocal<LoginLog> loginThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger loginLogger;
    private static ThreadLocal<PaymentLog> paymentThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger paymentLogger;
    private static ThreadLocal<AddItemLog> addItemThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger addItemLogger;
    private static ThreadLocal<CostItemLog> costItemThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger costItemLogger;
    private static ThreadLocal<GuideLog> guideThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger guideLogger;
    private static ThreadLocal<LevelLog> levelThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger levelLogger;
    private static ThreadLocal<ActionLog> actionThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger actionLogger;
    private static ThreadLocal<ActivityLog> activityThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger activityLogger;
    private static ThreadLocal<HeartbeatLog> heartbeatThreadLocal = new ThreadLocal<>() ;
    private static RollingLogger heartbeatLogger;

    public static void initialize( String logDir, String gameId ){

        if( ! logDir.endsWith( "/" ) ){
            logDir += "/";
        }


        String dateFromat = "yyyy-MM-dd";

        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            registerLogger = new RollingLogger( logDir + gameId + ".game.register.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            loginLogger = new RollingLogger( logDir + gameId + ".game.login.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            paymentLogger = new RollingLogger( logDir + gameId + ".game.payment.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            addItemLogger = new RollingLogger( logDir + gameId + ".game.addItem.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            costItemLogger = new RollingLogger( logDir + gameId + ".game.costItem.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            guideLogger = new RollingLogger( logDir + gameId + ".game.guide.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            levelLogger = new RollingLogger( logDir + gameId + ".game.level.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            actionLogger = new RollingLogger( logDir + gameId + ".game.action.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            activityLogger = new RollingLogger( logDir + gameId + ".game.activity.%s.txt", dateFromat, calendar);
        }
        {
            RollingCalendar calendar = new RollingCalendar();
            calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
            heartbeatLogger = new RollingLogger( logDir + gameId + ".game.heartbeat.%s.txt", dateFromat, calendar);
        }
    }

    public static  RegisterLog getRegisterLog(){
        RegisterLog log =  registerThreadLocal.get();
        if( log == null ){
            log = new RegisterLog();
            registerThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  RegisterLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        registerLogger.appendLog(  sb.toString() );
    }


    public static  LoginLog getLoginLog(){
        LoginLog log =  loginThreadLocal.get();
        if( log == null ){
            log = new LoginLog();
            loginThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  LoginLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        loginLogger.appendLog(  sb.toString() );
    }


    public static  PaymentLog getPaymentLog(){
        PaymentLog log =  paymentThreadLocal.get();
        if( log == null ){
            log = new PaymentLog();
            paymentThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  PaymentLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        paymentLogger.appendLog(  sb.toString() );
    }


    public static  AddItemLog getAddItemLog(){
        AddItemLog log =  addItemThreadLocal.get();
        if( log == null ){
            log = new AddItemLog();
            addItemThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  AddItemLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        addItemLogger.appendLog(  sb.toString() );
    }


    public static  CostItemLog getCostItemLog(){
        CostItemLog log =  costItemThreadLocal.get();
        if( log == null ){
            log = new CostItemLog();
            costItemThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  CostItemLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        costItemLogger.appendLog(  sb.toString() );
    }


    public static  GuideLog getGuideLog(){
        GuideLog log =  guideThreadLocal.get();
        if( log == null ){
            log = new GuideLog();
            guideThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  GuideLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        guideLogger.appendLog(  sb.toString() );
    }


    public static  LevelLog getLevelLog(){
        LevelLog log =  levelThreadLocal.get();
        if( log == null ){
            log = new LevelLog();
            levelThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  LevelLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        levelLogger.appendLog(  sb.toString() );
    }


    public static  ActionLog getActionLog(){
        ActionLog log =  actionThreadLocal.get();
        if( log == null ){
            log = new ActionLog();
            actionThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  ActionLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        actionLogger.appendLog(  sb.toString() );
    }


    public static  ActivityLog getActivityLog(){
        ActivityLog log =  activityThreadLocal.get();
        if( log == null ){
            log = new ActivityLog();
            activityThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  ActivityLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        activityLogger.appendLog(  sb.toString() );
    }


    public static  HeartbeatLog getHeartbeatLog(){
        HeartbeatLog log =  heartbeatThreadLocal.get();
        if( log == null ){
            log = new HeartbeatLog();
            heartbeatThreadLocal.set( log );
        }else{
            log.reset();
        }

        return log;
    }

    public static void appendLog(  HeartbeatLog log ){
        StringBuilder sb = getStringBuilder();
        log.writeTo( sb );
        heartbeatLogger.appendLog(  sb.toString() );
    }



    private static StringBuilder getStringBuilder(){
        StringBuilder sb = sbLocal.get();
        if( sb == null ){
            sb = new StringBuilder();
            sbLocal.set( sb );
        }

        sb.setLength( 0 );
        return sb;
    }

     public static String getCurrentLogTime( ) {
        SimpleDateFormat sdf = threadLocalSDF.get();
        if ( sdf == null ) {
            sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
            threadLocalSDF.set( sdf );
        }
        return sdf.format( new Date( ) );
    }

}